package com.jiangjiang.eshop.finance.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiangjiang.eshop.finance.constant.PurchaseSettlementOrderApproveResult;
import com.jiangjiang.eshop.finance.constant.PurchaseSettlementOrderStatus;
import com.jiangjiang.eshop.finance.convert.PurchaseSettlementOrderConvert;
import com.jiangjiang.eshop.finance.dao.PurchaseSettlementOrderMapper;
import com.jiangjiang.eshop.finance.domain.PurchaseSettlementOrder;
import com.jiangjiang.eshop.finance.dto.PurchaseSettlementOrderDTO;
import com.jiangjiang.eshop.finance.dto.PurchaseSettlementOrderItemDTO;
import com.jiangjiang.eshop.finance.dto.PurchaseSettlementOrderQuery;
import com.jiangjiang.eshop.wms.service.WmsFacadeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @ClassName PurchaseSettlementOrderService
 * @Description TODO
 * @Author jhw
 * @Date 2021/9/15 23:57
 * @Version 1.0
 **/
@Service
public class PurchaseSettlementOrderService extends ServiceImpl<PurchaseSettlementOrderMapper, PurchaseSettlementOrder> {

    @Autowired
    private PurchaseSettlementOrderConvert purchaseSettlementOrderConvert;
    @Autowired
    private PurchaseSettlementOrderItemService purchaseSettlementOrderItemService;

    @Autowired
    private WmsFacadeService wmsFacadeService;


    /**
     * 保存采购结算单数据
     *
     * @param order 采购结算单
     */
    public Boolean saveSettlementOrder(PurchaseSettlementOrderDTO order) {
        // 保存采购结算单数据
        double totalAmount = order.getItems().stream().mapToDouble(entity -> entity.getArrivalCount() * entity.getPurchasePrice()).sum();
        order.setStatus(PurchaseSettlementOrderStatus.EDITING);
        order.setTotalSettlementAmount(totalAmount);
        PurchaseSettlementOrder purchaseSettlementOrder = purchaseSettlementOrderConvert.convertDTO2Entity(order);
        this.save(purchaseSettlementOrder);

        // 保存采购结算单明细数据
        order.getItems().forEach(item -> item.setPurchaseSettlementOrderId(purchaseSettlementOrder.getId()));
        purchaseSettlementOrderItemService.saveBatchItems(order.getItems());
        // 通知wms采购结算单创建完成
        wmsFacadeService.informCreatePurchaseSettlementOrderEvent(order.getPurchaseInputOrderId());
        return true;
    }

    /**
     * 采购结算单分页数据查询
     *
     * @param req 分页查询条件
     * @return 分页查询结果
     */
    public Page<PurchaseSettlementOrderDTO> queryForPage(PurchaseSettlementOrderQuery req) {
        Page<PurchaseSettlementOrder> page = new Page<>(req.getPageNo(), req.getPageNo(), true);
        LambdaQueryWrapper<PurchaseSettlementOrder> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(req.getSupplierId() != null, PurchaseSettlementOrder::getSupplierId, req.getSupplierId())
                .eq(req.getStatus() != null, PurchaseSettlementOrder::getStatus, req.getStatus());
        return purchaseSettlementOrderConvert.convertPage2DTO(this.getBaseMapper().selectPage(page, wrapper));
    }


    /**
     * 根据id 查询采购结算单
     *
     * @param id 采购结算单id
     * @return 查询结果
     */
    public PurchaseSettlementOrderDTO queryById(Long id) {
        PurchaseSettlementOrderDTO dto = purchaseSettlementOrderConvert.convertEntity2DTO(this.getById(id));
        //补充采购结算单明细数据
        dto.setItems(purchaseSettlementOrderItemService.queryByPurchaseSettlementOrderId(id));
        return dto;
    }

    /**
     * 采购结算单编辑
     * @param order
     * @return
     */
    public Boolean updateSettlementOrder(PurchaseSettlementOrderDTO order) {
        // 保存采购结算单数据
        double totalAmount = order.getItems().stream().mapToDouble(entity -> entity.getArrivalCount() * entity.getPurchasePrice()).sum();
        order.setTotalSettlementAmount(totalAmount);
        PurchaseSettlementOrder purchaseSettlementOrder = purchaseSettlementOrderConvert.convertDTO2Entity(order);
        this.updateById(purchaseSettlementOrder);

        // 保存采购结算单明细数据
        purchaseSettlementOrderItemService.updateBatchItems(order.getItems());
        return true;
    }

    /**
     * 采购结算单提交审核
     * @param id
     * @return
     */
    public Boolean submitApprove(Long id){
        return updateStatus(id, PurchaseSettlementOrderStatus.WAIT_FOR_APPROVE);
    }

    /**
     * 采购结算单审核
     * @param id
     * @return
     */
    public Boolean approve(Long id,Integer approveResult){
        if(PurchaseSettlementOrderApproveResult.REJECTED.equals(approveResult)){
            this.updateStatus(id, PurchaseSettlementOrderStatus.EDITING);
        }

        if(PurchaseSettlementOrderApproveResult.PASSED.equals(approveResult)){
            PurchaseSettlementOrder order = this.getById(id);
            this.updateStatus(id, PurchaseSettlementOrderStatus.FINISHED);
            // 通知wms中心，“完成采购结算单”事件发生了
            wmsFacadeService.informFinishedPurchaseSettlementOrderEvent(order.getPurchaseInputOrderId());
        }
        return true;

    }


    /**
     * 更新采购结算单状态
     * @param id 采购结算单id
     * @param status 状态
     * @return 处理结果
     */
    public Boolean updateStatus(Long id,Integer status){
        LambdaUpdateWrapper<PurchaseSettlementOrder> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(PurchaseSettlementOrder::getId, id)
                .set(PurchaseSettlementOrder::getStatus, status)
                .set(PurchaseSettlementOrder::getGmtModified, new Date());
        return this.update(wrapper);
    }


    /**
     * 根据采购结算周期获取完结的采购结算单
     * @param supplierId 供应商id
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @return 查询结果
     */
    public List<PurchaseSettlementOrderDTO> queryFinishedBySettlePeriod(Long supplierId,Date startDate,Date endDate){
        LambdaQueryWrapper<PurchaseSettlementOrder> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(PurchaseSettlementOrder::getSupplierId, startDate)
                .eq(PurchaseSettlementOrder::getStatus,3)
                .between(PurchaseSettlementOrder::getGmtCreate, startDate, endDate);

        return purchaseSettlementOrderConvert.convert2DTOList(this.list(wrapper));
    }
}
